#include <pthread.h>
#include <syslog.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
sigset_t mask;

extern int already_running(void);
extern void daemonize(const char *cmd); 
void reread(void){
    /*
        ...
    */
    syslog(LOG_INFO, "reread conf");
}

void * thr_fn(void *arg){
    int err, signo;

    for(;;){
        err = sigwait(&mask, &signo);
        if(err != 0){
            syslog(LOG_ERR, "sigwait failed");
            exit(1);
        }

        switch(signo){
            case SIGHUP:
                syslog(LOG_INFO, "Re-reading configuration file");
                reread();
                break;
            case SIGTERM:
                syslog(LOG_INFO, "got SIGTERM; exiting");
                exit(0);
            default:
                syslog(LOG_INFO, "unexpected signal %d\n", signo);
        }
        return 0;
    }
}

int main(int argc, char *argv[]){
    int err;
    pthread_t tid;
    char *cmd;
    struct sigaction sa;

    if((cmd = strchr(argv[0], '/')) == NULL){
        cmd = argv[0];
    }else{
        cmd++;
    }
    
    /*
        become a daemon
    */
    daemonize(cmd);

    /*
        make sure only one copy of the daemon is running.
    */
    if(already_running()){
        syslog(LOG_ERR, "daemon already running");
        exit(1);
    }

    /*
        restore SIGHUP default and block all signals.
    */
    sa.sa_handler = SIG_DFL;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if(sigaction(SIGHUP, &sa, NULL) < 0){
        syslog(LOG_ERR, "can't restore SIGHUP default");
        exit(1);
    }
    sigfillset(&mask);
    if((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0){
        syslog(LOG_ERR, "SIG_BLOCK error");
    }

    /*
        create a thread to handle SIGHUP and SIGTERM
    */
    err = pthread_create(&tid, NULL, thr_fn, 0);
    if(err != 0){
        syslog(LOG_ERR, "can't create thread");
    }

    sleep(100);
    exit(0);
}